import numpy as np
import sys
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
class Gradient_descent(object):
    def __init__(self):
        self.ans = 0
        self.x = []
        self.y = []
        self.z = []
    def function(self,x,y):
        z = x**2 + y**2
        return z
    def gradient(self,x,y):
        return 2*x,2*y # 

    def gradientDescent(self,init,step):
        #interval
        x,y = init
        self.x.append(x)
        self.y.append(y)
        h = step
        f_delta = self.function(x,y)
        f_current = self.function(x,y)
        self.z.append(f_current)
        while f_delta > np.power(0.1,10):
            delta_x,delta_y = self.gradient(x,y)
            x = x - delta_x * h
            y = y - delta_y * h
            self.x.append(x)
            self.y.append(y)
            f_delta = f_current - self.function(x,y)
            f_current = self.function(x,y)
            self.z.append(f_current)
            print(x,y)

        self.ans = f_current
    def draw(self):
        fig = plt.figure()
        ax = fig.add_subplot(111,projection = '3d')
        ax.scatter(self.x, self.y, self.z, marker = "x",c = "red")
        x = np.linspace(0,10,100)
        y = np.linspace(0,10,100)
        X,Y = np.meshgrid(x,y)
        Z = self.function(X,Y)
        ax.plot_surface(X,Y,Z)
        plt.show()

a = Gradient_descent()
a.gradientDescent((10,10),0.1)
print(a.ans)
a.draw()
